home *** CD-ROM | disk | FTP | other *** search
-
-
- /*********************************************************/
- /* */
- /* ANALOG JOYSTICK DEMO */
- /* */
- /* Copyright (c) 1989, David Kinzer, All Rights Reserved */
- /* */
- /* Permission hereby granted to redistribute this */
- /* program in unmodified form in a not for profit manner.*/
- /* */
- /* Permission hereby granted to use this software freely */
- /* in programs, commercial or not. */
- /* */
- /*********************************************************/
- /* */
- /* JoyDemo.c */
- /* */
- /* This program demonstrates the use of an Analog */
- /* Joystick input device on the Amiga (tm) Computer. */
- /* This program also demonstrates the use of libraries, */
- /* screens, and windows. */
- /* */
- /* */
- /*********************************************************/
-
-
- /* The following includes some header files which define
- some types and structures used by this program. Note
- that these include files will themselves include more
- files so that everything they need is also included. */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
-
- /* Include our own defines for the Joystick portion of
- the program. The use of quotes around the include
- file name tells the compiler to look in the current
- directory for the specified file. If not found, the
- compiler will look in the default library. */
-
- #include "ajoystick.h"
-
- /* The following variables are required to use the
- libraries. The libraries are loaded into ram so many
- programs can use them at the same time. This
- reduces duplication and therefore reduces the ammount
- of ram needed for multitasking. These variables are
- pointers to the base of the library entry point. They
- must be global variables so the 'C' library routines
- (which call the actual Amiga library routines) can
- find them during the linking process. The 'C' library
- routine adds an offset to this pointer and goes to the
- subroutine located there. */
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
-
- /* The following will be used during the open library to
- ask for a particular revision or greater in the
- library. A value of Zero says open any revision.
- This would be useful if you used one of the new version
- 1.2 routines which did not exist in V1.1. If you
- were to call a non-existant routine, the system will
- crash. */
-
- #define INTUITION_REV 0L
- #define GRAPHICS_REV 0L
-
- /* Here we define the height of the title bar on a
- window so our program will be able to skip over
- that space, as well as the width of the window
- boarders. */
-
- #define TITLEHEIGHT 10L
- #define BOTTOMWIDTH 1L
- #define LEFTWIDTH 2L
- #define RIGHTWIDTH 2L
-
- /* Here is where we will define the font that we will
- use for our display. It defines the font that will
- be used by the text function for rendering in any
- window on our screen. */
-
- struct TextAttr MyFont =
- {
- (STRPTR)"topaz.font", /* Font Name */
- TOPAZ_EIGHTY, /* Font Height */
- FS_NORMAL, /* Style */
- FPF_ROMFONT, /* Preferences */
- };
-
- /* Next we set up the data structure which opens the
- screen. Notice we include the address of our font
- structure in this structure. */
-
- struct NewScreen OurScreen =
- {
- 0, /* the left edge has to be zero */
- 0, /* top edge, start at top of screen */
- 640, /* Width, we want High Resolution */
- 200, /* Height, we want non-interlace */
- 2, /* Depth, Two Planes, 4 colors */
- 0,1, /* DetailPen and BlockPen specs */
- HIRES, /* Let's go for High Res */
- CUSTOMSCREEN, /* screen type, not the Workbench */
- &MyFont, /* use the font we said to */
- (STRPTR)"Joystick Screen",/* Screen name, in title bar*/
- NULL, /* screen gadget */
- NULL, /* No custom Bitmap */
- };
-
-
- /* OK, here comes the program. */
-
- VOID main()
- {
- /* The following are used to open the screen and window. */
- struct Screen *Screen_ptr;
- struct NewWindow OurWindow;
- struct Window *Window_ptr;
-
- /* The following variables are used in the demo loop. */
- struct AJoyData *JP;
- long pcolor;
- struct message *msgptr = NULL;
- long old_x = -1;
- long old_y = -1;
- long old_color = 0;
-
- /* Declare the return type of the functions used. */
- APTR OpenLibrary(),OpenScreen(),OpenWindow();
- APTR AllocMem(),GetMsg();
-
- /* Declare our function to keep Lattice (tm) happy. */
- VOID DrawBox();
-
-
- /* Open the Intuition library. The result returned by
- this call is a pointer to the jump table of the
- Intuition library. This call will load the library
- from disk if it is not already loaded. If this call
- returns zero, something is wrong and Intuition is
- not available to us. If this is true, attempting to
- use the library will cause the machine to crash, so
- we should exit the program. */
-
- IntuitionBase = (struct IntuitionBase *) OpenLibrary(
- (STRPTR)"intuition.library",INTUITION_REV);
- if (IntuitionBase == NULL)
- exit(FALSE);
-
- /* Same with the Graphics Library */
-
- GfxBase = (struct GfxBase *)OpenLibrary((STRPTR)
- "graphics.library",GRAPHICS_REV);
- if (GfxBase == NULL)
- exit(FALSE);
-
-
- /* Now it is time to get our screen. The OpenScreen call
- does a bunch of neat stuff for us like getting chip
- memory for the screen and RastPort structures. We
- could do all this stuff for ourselves, but why? */
-
- Screen_ptr = (struct Screen *)OpenScreen(&OurScreen);
- if (Screen_ptr == NULL)
- exit(FALSE);
-
-
- /* We are going to fill out the window structure in order
- so we can open a window on our new screen. Our window
- will have a few gadgets for us to play with. Since
- one of the IDCMP flags is set, this program will open
- a message port which we will monitor to see when the
- window should be closed. */
-
- OurWindow.LeftEdge = 20;
- OurWindow.TopEdge = 20;
- OurWindow.Width = 512+LEFTWIDTH+RIGHTWIDTH;
- OurWindow.Height = 128+TITLEHEIGHT+BOTTOMWIDTH;
- OurWindow.DetailPen = 0;
- OurWindow.BlockPen = 1;
- OurWindow.Title = (STRPTR)"Joystick Drawing Window";
- OurWindow.Flags = WINDOWCLOSE | SMART_REFRESH
- | ACTIVATE | WINDOWDRAG
- | WINDOWDEPTH | NOCAREREFRESH;
- OurWindow.IDCMPFlags = CLOSEWINDOW;
- OurWindow.Type = CUSTOMSCREEN;
- OurWindow.FirstGadget = NULL;
- OurWindow.CheckMark = NULL;
- OurWindow.Screen = Screen_ptr;
- OurWindow.BitMap = NULL;
- OurWindow.MinWidth = 512+LEFTWIDTH+RIGHTWIDTH;
- OurWindow.MinHeight = 128+TITLEHEIGHT+BOTTOMWIDTH;
- OurWindow.MaxWidth = 512+LEFTWIDTH+RIGHTWIDTH;
- OurWindow.MaxHeight = 128+TITLEHEIGHT+BOTTOMWIDTH;
-
- /* Now open the window on our screen. */
-
- Window_ptr = (struct Window *)OpenWindow(&OurWindow);
- if (Window_ptr == NULL)
- exit(FALSE);
-
- /* Move the graphics pen (an imaginary thing) to where
- we would like our text to be drawn. */
-
- Move(Window_ptr->RPort,20L,20L);
-
- /* Now let's send some text out to the screen */
-
- Text(Window_ptr->RPort,(STRPTR)"Joystick Draw",13L);
-
- /* Let's outline the text with a box, this is our own
- function */
-
- DrawBox(Window_ptr->RPort,1,12,22,16,128);
-
- /* */
- /* Now we get to the Analog Joystick part. */
- /* */
-
-
- /* Define some conversion functions that change the
- 0-255 input values into the coordinates for drawing
- into our window. */
-
- #define fx(x) (x / 128 + LEFTWIDTH)
- #define fy(y) (y / 512 + TITLEHEIGHT)
-
- /* Allocate some public memory for a data structure that
- the ReadAJoystick will return the data to us in. It
- is not necessary for this to be public for this
- example program since we are linking the driver with
- our program, but should this become a library, this
- would be required. (It doesn't hurt to think ahead
- some.) */
-
- JP = (struct AJoyData *)AllocMem((long)sizeof
- (struct AJoyData),MEMF_PUBLIC);
-
- /* Continue only if the allocate worked. */
-
- if (JP) {
-
- /* Call the open routine of our driver. We are
- requesting Unit 1 (the right mouse port), and we
- want it to give us a single pressed indication for
- each time button 2 is pressed. (This means button
- 1 [as well as 3 and 4 if your joystick is so
- equipped] will report pressed as long as the user
- holds it down.) */
-
- if (OpenAJoystick(AJOYUNIT1 | U1B2SINGLE)) {
-
- /* Set the graphics pen to color 1 (actual color
- depends upon preferences) */
-
- pcolor = 1;
- SetAPen(Window_ptr->RPort,pcolor);
-
- /* Loop until user clicks close box on the window. */
-
- do {
-
- /* Read settings of the Analog joystick and buttons. */
-
- ReadAJoystick(AJOYUNIT1,JP);
-
- /* Check button 2. Button 2 indicates the user wants
- to change the color that he is drawing with. Note
- that if we had not specified U1B2SINGLE on the open
- call, the color would cycle as long as the user held
- the button down. This would make it difficult for
- him or her to select a color. If the button is
- pressed, change the color variable and write the
- new color on the display. */
-
- if (JP->button2 != BUTTONUP) {
- pcolor = (pcolor+1) % 4;
- SetAPen(Window_ptr->RPort,pcolor);
- WritePixel(Window_ptr->RPort,old_x,old_y);
- WritePixel(Window_ptr->RPort,old_x+1,old_y);
- }
-
- /* If the joystick position has moved, we need to decide
- if are to clean up the screen where we were drawing.
- If the button is pressed, we leave the current color
- on the screen. This is done in conjunction with the
- statement below. If the old color matches the current
- color, we just leave it. If it does not match, we
- replace it with the color that used to be there. We
- then move to the new position, save the color that
- was there, and write out the new color. */
-
- if ((fx(JP->x) != old_x) ||
- (fy(JP->y) != old_y)) {
- if (pcolor != old_color) {
- SetAPen(Window_ptr->RPort,old_color);
- WritePixel(Window_ptr->RPort,old_x,
- old_y);
- WritePixel(Window_ptr->RPort,old_x+1,
- old_y);
- SetAPen(Window_ptr->RPort,pcolor);
- }
- old_x = fx(JP->x);
- old_y = fy(JP->y);
- old_color = ReadPixel(Window_ptr->RPort,
- old_x,old_y);
-
- WritePixel(Window_ptr->RPort,old_x,old_y);
- WritePixel(Window_ptr->RPort,old_x+1,old_y);
- }
-
- /* If button 1 is pressed, the user wants to draw in the
- window. As long as the button is held, points will
- change to the current color. We do this by changing
- the saved color to the current color so when the
- joystick is moved the color is retained. */
-
- if (JP->button1 != BUTTONUP) {
- old_color = pcolor;
- }
-
- /* Check for any messages coming in to our program. The
- GetMsg routine returns a pointer to the first message
- in the queue, if any. If there are no messages, it
- returns a NULL. */
-
- } while (!(msgptr = (struct message *)
- GetMsg(Window_ptr->UserPort)));
-
- /* We looped until a message arrived at the IDCMP port.
- Since we only asked for one type of message, we are
- assured that it is the close window message. If we
- had asked for more types, we would have to decode it
- to see what type of message it is. For our case, we
- just reply the message, clean up, and we're done. */
-
- ReplyMsg(msgptr);
-
- /* Turn off the joystick routines. */
-
- CloseAJoystick();
- }
-
- /* Free up the memory we allocated for our data
- structure. */
-
- FreeMem(JP,(long)sizeof(struct AJoyData));
-
- }
-
-
- /* Close up the window, and then the screen. Then we
- are done. */
-
- CloseWindow(Window_ptr);
- CloseScreen(Screen_ptr);
-
- exit(TRUE);
-
- }
-
-
- /* Here we have our own function which draws a box on
- the screen. It calls an Amiga function called
- PolyDraw which draws polygons on the display area.
- We change the color of the pen to what is desired,
- draw the box and set it back. We also preserve the
- graphics pen location. */
-
-
- VOID DrawBox(RP,PenColor,Top,Bottom,Left,Right)
-
- struct RastPort *RP;
- int PenColor,Top,Bottom,Left,Right;
-
- {
- int OldPenColor,x,y;
- short points[4][2];
-
- /* Fill in the points of our box polygon that will
- be used by the DrawPoly function. The array must
- be made up of 16 bit numbers. */
-
- points [3][0] = Left;
- points [3][1] = Top;
- points [0][0] = Right;
- points [0][1] = Top;
- points [1][0] = Right;
- points [1][1] = Bottom;
- points [2][0] = Left;
- points [2][1] = Bottom;
-
-
- /* The Amiga routines should include ones to find out
- the current color and location of the graphics pen,
- but it was not to be. We will just go grab the
- information from the RastPort structure. */
-
- OldPenColor = RP->FgPen;
- x = RP->cp_x;
- y = RP->cp_y;
-
- /* Set the pen to what we desire, and move the pen
- to the top left corner of the Box. */
-
- SetAPen(RP,(long)PenColor);
- Move(RP,(long)Left,(long)Top);
-
- /* Draw the Box. */
-
- PolyDraw(RP,4L,points);
-
- /* And set everything back again. */
-
- SetAPen(RP,(long)OldPenColor);
- Move(RP,(long)x,(long)y);
-
- }
-
-
- /* End: JoyDemo.c */
-
-